home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr25 / gnuplsrc.zip / PRINT.C < prev    next >
C/C++ Source or Header  |  1993-03-21  |  14KB  |  427 lines

  1. #ifdef INCRCSDATA
  2. static char RCSid[]="$Id: print.c,v 1.2 1992/07/26 12:37:10 fearick Exp fearick $" ;
  3. #endif
  4.  
  5. /****************************************************************************
  6.  
  7.     PROGRAM: gnushell
  8.     
  9.     a shell for gnuplot to allow plotting on pm with minimum hassle
  10.  
  11.     MODULE:  print.c -- support for printing graphics under OS/2 
  12.         
  13. ****************************************************************************/
  14.  
  15. /*
  16.     Copyright (c) 1992, Roger Fearick.
  17.     All rights reserved
  18.      
  19.     THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT WARRANTIES OF ANY KIND. 
  20.    
  21.     Permission is hereby granted for personal, non-commercial use of this 
  22.     software.You are granted the right to use, modify, and redistribute 
  23.     it for for non-commercial purposes, provided that all copyright 
  24.     notices remain intact and all changes are clearly documented.      
  25.     THE AUTHOR MAKES NO WARRANTY OF ANY KIND WITH RESPECT TO THIS PRODUCT 
  26.     AND EXPLICITLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY 
  27.     OR FITNESS FOR ANY PARTICULAR PURPOSE.                               
  28.  
  29. */
  30.  
  31. /* Update Log
  32. **
  33.  * $Log: print.c,v $
  34.  * Revision 1.2  1992/07/26  12:37:10  fearick
  35.  * Initial 32-bit version
  36.  *
  37.  * Revision 1.1  1992/07/25  15:44:41  fearick
  38.  * Initial revision
  39.  *
  40.  *
  41. */ 
  42.  
  43. #define INCL_DOSPROCESS
  44. #define INCL_DOSSEMAPHORES
  45. #define INCL_DEV
  46. #define INCL_PM
  47. #define INCL_WIN
  48. #include <os2.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <process.h>
  53. #include "gnushell.h"
  54.  
  55. typedef struct {            // for print thread
  56.     HWND  hwnd ;
  57.     char  *szPrintFile ;    // file for printer output if not to printer
  58.     } PRINTPARAMS ;
  59.  
  60. static struct { 
  61.     long    lTech ;     // printer technology
  62.     long    lVer ;      // driver version
  63.     long    lWidth ;    // page width in pels
  64.     long    lHeight ;   // page height in pels
  65.     long    lWChars ;   // page width in chars    
  66.     long    lHChars ;   // page height in chars    
  67.     long    lHorRes ;   // horizontal resolution pels / metre
  68.     long    lVertRes ;  // vertical resolution pels / metre
  69.     } prCaps ;
  70.  
  71. static char    szPrinting [] = "Printing" ;
  72. static float   flXFrac = (float) 0.6 ;   /* print area fractions */
  73. static float   flYFrac = (float) 0.5 ;
  74.  
  75. static CHAR     achPrinterData[256] ;
  76. static DRIVDATA driv = {sizeof( DRIVDATA) } ;
  77. static PDRIVDATA pdriv = NULL ;
  78. static CHAR     achDefPrinterName[34] ;
  79. static char     szPrintFile[16] = {0} ;
  80. static DEVOPENSTRUC devop ;
  81.  
  82. HDC             OpenPrinterDC( HAB, LONG, char* ) ;
  83. void            ThreadPrintPage( PRINTPARAMS* ) ;
  84. void            SetPrinterMode( HWND ) ;
  85.  
  86. MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  87. /*
  88. **  Handle messages for print commands for 1- and 2-d spectra
  89. ** (i.e for the appropriate 1-and 2-d child windows )
  90. */
  91.     {
  92.     static BYTE abStack[4096] ;  
  93.     PBYTE pStack = abStack;
  94.     TID tid ;
  95.     static PRINTPARAMS tp ;
  96.     char *pszMess ;
  97.     static char szBusy[] = "Busy - try again later" ;
  98.     static char szStart[] = "Printing started" ;
  99.     static HEV semPrint = 0L ;
  100.     long lErr ;
  101.     static char szTemp[32] ;
  102.  
  103.     if( semPrint == 0L ) {
  104.         DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
  105.         }
  106.  
  107.     switch( msg ) {
  108.         
  109.         case WM_USER_PRINT_BEGIN:
  110.         
  111.             if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
  112.                 pszMess = szBusy ;
  113.                 WinMessageBox( HWND_DESKTOP,
  114.                                hWnd, 
  115.                                pszMess,
  116.                                "Gnushell",
  117.                                0,
  118.                                MB_OK | MB_ICONEXCLAMATION ) ;
  119.                 }
  120.             else {
  121.                 pszMess = szStart ;
  122.                 tp.hwnd = hWnd ;
  123.                 if( szPrintFile[0] == '\0' )
  124.                     tp.szPrintFile = NULL ;
  125.                 else
  126.                     tp.szPrintFile = szPrintFile ;
  127.                 DosCreateThread( &tid, (PFNTHREAD)ThreadPrintPage, (ULONG)&tp, 0L, 8192L ) ;
  128.                 }
  129.             break ;
  130.  
  131.  
  132.         case WM_USER_PRINT_OK :
  133.  
  134.             WinMessageBox( HWND_DESKTOP,
  135.                            hWnd, 
  136.                            "Print done",
  137.                            "Gnushell",
  138.                            0,
  139.                            MB_OK | MB_ICONEXCLAMATION ) ;
  140.              DosReleaseMutexSem( semPrint ) ;
  141.              break ;
  142.  
  143.         case WM_USER_DEV_ERROR :
  144.  
  145.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  146.             sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
  147.             WinMessageBox( HWND_DESKTOP,
  148.                            hWnd, 
  149.                            szTemp,
  150.                            "Gnushell",
  151.                            0,
  152.                            MB_OK | MB_ICONEXCLAMATION ) ;
  153.              DosReleaseMutexSem( semPrint ) ;
  154.              break ;
  155.  
  156.         case WM_USER_PRINT_ERROR :
  157.         
  158.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  159.             sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
  160.             WinMessageBox( HWND_DESKTOP,
  161.                            hWnd, 
  162.                            szTemp,
  163.                            "Gnushell",
  164.                            0,
  165.                            MB_OK | MB_ICONEXCLAMATION ) ;
  166.              DosReleaseMutexSem( semPrint ) ;
  167.              break ;
  168.  
  169.         case WM_USER_PRINT_QBUSY :
  170.  
  171.             return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
  172.             
  173.         default : break ;
  174.         }
  175.         
  176.     return 0L ;
  177.     }
  178.  
  179. short QueryPrinterCaps( HWND hwnd )
  180. /*
  181. **  Returns a short specifying the printer caps
  182. */
  183.     {
  184.     HDC hdc ;
  185.     short shCaps = 0 ;
  186.     long lTech ;
  187.     
  188.     if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), OD_INFO, NULL )) != DEV_ERROR ) {
  189.         DevQueryCaps( hdc, CAPS_TECHNOLOGY, 1L, &lTech ) ;
  190.         DevCloseDC( hdc ) ;
  191.  
  192.         shCaps = ((lTech==CAPS_TECH_VECTOR_PLOTTER)||(lTech==CAPS_TECH_POSTSCRIPT)) ?
  193.                  QP_CAPS_FILE : QP_CAPS_NORMAL ;
  194.         }
  195.     return shCaps ; 
  196.     }
  197.     
  198. void SetupPrinter( HWND hwnd )
  199. /*
  200. **  Set up the printer
  201. **
  202. */
  203.     {
  204.     QPRINT qp ;
  205.     
  206.     HDC hdc ;
  207.     if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), OD_INFO, NULL )) != DEV_ERROR ) {
  208.         DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
  209.         DevCloseDC( hdc ) ;
  210.         qp.xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
  211.         qp.ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
  212.         qp.xfrac = flXFrac ;
  213.         qp.yfrac = flYFrac ;
  214.         qp.name[0] = 0 ;
  215.         szPrintFile[0] = 0 ;
  216.         qp.caps  = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
  217.                    QP_CAPS_FILE : QP_CAPS_NORMAL ;
  218.         if( WinDlgBox( HWND_DESKTOP,
  219.                       hwnd,
  220.                       (PFNWP)QPrintDlgProc,
  221.                       0L,
  222.                       ID_QPRINT,
  223.                       &qp ) == DID_OK ) {
  224.             flXFrac = qp.xfrac ;
  225.             flYFrac = qp.yfrac ;
  226.             if( qp.caps & QP_CAPS_FILE ) {
  227.                 if( qp.name[0] != 0 ) strcpy( szPrintFile, qp.name ) ;
  228.                 }
  229.             }    
  230.         }   
  231.     }
  232.  
  233. void SetPrinterMode( HWND hwnd )
  234. /*
  235. **  call up printer driver's own setup dialog box
  236. */
  237.     {
  238.     HAB hab ;
  239.     LONG lBytes ;
  240.     char achDeviceName[32] ;
  241.     
  242.     hab = WinQueryAnchorBlock( hwnd ) ;
  243.     
  244.     achDeviceName[0] = 0 ;
  245.     lBytes = DevPostDeviceModes( hab,
  246.                                  NULL,
  247.                                  devop.pszDriverName,
  248.                                  driv.szDeviceName,
  249.                                  NULL,
  250.                                  DPDM_POSTJOBPROP ) ;
  251.     if( pdriv != NULL ) free( pdriv ) ;
  252.     pdriv = malloc( (short)lBytes ) ;
  253.     DevPostDeviceModes( hab,
  254.                         pdriv,
  255.                         devop.pszDriverName,
  256.                         driv.szDeviceName,
  257.                         NULL,
  258.                         DPDM_POSTJOBPROP ) ;
  259.     }
  260.  
  261. void ThreadPrintPage( PRINTPARAMS *ptp )
  262. /*
  263. **  thread to set up printer DC and print page 
  264. **
  265. **  Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
  266. **
  267. */
  268.     {    
  269.     HAB         hab ;       // thread anchor block nandle
  270.     HDC         hdc ;       // printer device context handle
  271.     HPS         hps ;       // presentation space handle
  272.     SHORT       msgRet ;    // message posted prior to return (end of thread)
  273.     SIZEL       sizPage ;   // size of page for creation of presentation space
  274.     LONG        alPage[2] ; // actual size of printer page in pixels
  275.     RECTL       rectPage ;  // viewport on page into which we draw
  276.     LONG        lColors ;
  277.     char        *szPrintFile ;
  278.     
  279.     hab = WinInitialize( 0 ) ;
  280.     
  281.     szPrintFile = ptp->szPrintFile == NULL ? NULL : strdup( ptp->szPrintFile ) ;
  282.     
  283.     if( (hdc = OpenPrinterDC( hab, 0L, szPrintFile )) != DEV_ERROR ) {
  284.     
  285.             // create presentation space for printer
  286.  
  287.        sizPage.cx = 0 ;
  288.        sizPage.cy = 0 ;
  289.        hps = GpiCreatePS( hab,
  290.                           hdc,
  291.                           &sizPage,
  292.                           PU_ARBITRARY | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ) ;
  293.  
  294.        DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
  295.        DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
  296.        rectPage.xLeft = 0L ;
  297.        rectPage.xRight = alPage[0]*flXFrac ;
  298.        rectPage.yTop = alPage[1]*flYFrac ;//alPage[1]*(1.0-flYFrac) ;
  299.        rectPage.yBottom = 0L ; //  = alPage[1] ;
  300.        
  301.             // start printing
  302.                     
  303.         if( DevEscape( hdc, 
  304.                        DEVESC_STARTDOC,
  305.                        7L,
  306.                        "Gnushell plot",
  307.                        NULL,
  308.                        NULL ) != DEVESC_ERROR ) {
  309.  
  310.             ScalePS( hps, &rectPage, 0 ) ;
  311.             PlotThings( hps, lColors ) ;            
  312.             DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
  313.             msgRet = WM_USER_PRINT_OK ;
  314.             }
  315.         else
  316.             msgRet = WM_USER_PRINT_ERROR ;
  317.         
  318.         GpiDestroyPS( hps ) ;
  319.         DevCloseDC( hdc ) ;
  320.         }
  321.     else
  322.         msgRet = WM_USER_DEV_ERROR ;
  323.         
  324.     if( szPrintFile != NULL ) free( szPrintFile ) ;
  325.     DosEnterCritSec() ;
  326.     WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
  327.     WinTerminate( hab ) ;
  328.     }
  329.  
  330. HDC OpenPrinterDC( HAB hab, LONG lMode, char *szPrintFile )
  331. /*
  332. ** get printer info from os2.ini and set up DC
  333. **
  334. ** Input:  HAB hab  -- handle of anchor block of printing thread
  335. **         LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
  336. **         char *szPrintFile -- name of file for printer output, NULL
  337. **                  if to printer (only used for devices that support file
  338. **                  output eg plotter, postscript)
  339. **
  340. ** Return: HDC      -- handle of printer device context
  341. **                   = DEV_ERROR (=0) if error
  342. **
  343. ** see Petzold, PC Mag#4 vol 9 (27 Feb 1990) p317
  344. */
  345.     {
  346.     CHAR   *pchDelimiter ;
  347.     LONG   lType ;
  348.             // get default printer name    
  349.             
  350.     PrfQueryProfileString( HINI_PROFILE,
  351.                            "PM_SPOOLER",
  352.                            "PRINTER",
  353.                            ";",
  354.                            achDefPrinterName,
  355.                            (long) sizeof achDefPrinterName ) ;
  356.                            
  357.             // remove semicolon from name
  358.             
  359.     if( (pchDelimiter=strchr( achDefPrinterName, ';' )) != NULL )
  360.         *pchDelimiter = '\0' ;
  361.         
  362.     if( achDefPrinterName[0] == '\0' ) return DEV_ERROR ;
  363.     
  364.             // get printer info
  365.             
  366.     PrfQueryProfileString( HINI_PROFILE,
  367.                            "PM_SPOOLER_PRINTER",
  368.                            achDefPrinterName,
  369.                            ";;;;",
  370.                            achPrinterData,
  371.                            (long) sizeof achPrinterData ) ;
  372.                            
  373.             // parse printer info string
  374.     
  375.     if( (pchDelimiter = strchr( achPrinterData, ';' )) == NULL ) 
  376.         return DEV_ERROR ;
  377.         
  378.     devop.pszDriverName = pchDelimiter+1 ;
  379.     if( (pchDelimiter = strchr( devop.pszDriverName, ';' )) == NULL ) 
  380.         return DEV_ERROR ;
  381.         
  382.     devop.pszLogAddress = pchDelimiter+1 ;
  383.  
  384.     *(devop.pszLogAddress + strcspn( devop.pszLogAddress, ",;" )) = '\0' ;
  385.     *(devop.pszDriverName + strcspn( devop.pszDriverName, ",;" )) = '\0' ;
  386.     
  387.             // fill DRIVDATA struct
  388.             
  389.     if( (pchDelimiter=strchr( devop.pszDriverName, '.' )) != NULL ) {
  390.         *pchDelimiter = '\0' ;
  391.         strncpy( driv.szDeviceName, pchDelimiter+1, sizeof( driv.szDeviceName ) ) ;
  392.         }
  393.     else  {
  394.         devop.pdriv = NULL ;
  395.         driv.szDeviceName[0] = 0 ;
  396.         }
  397.         if( (pdriv != NULL ) ) //&& (strcmp( driv.szDeviceName, pdriv->szDeviceName) == 0 ) )
  398.             devop.pdriv = pdriv ;
  399.         else {
  400.             if( pdriv != NULL ) {
  401.                 free( pdriv ) ;
  402.                 pdriv = NULL ;
  403.                 }
  404.             devop.pdriv = &driv ;
  405.             }
  406.         if( szPrintFile != NULL ) {
  407.             devop.pszLogAddress = szPrintFile ;
  408.             }
  409.         
  410.             // set data type to RAW
  411.             
  412.     devop.pszDataType = "PM_Q_RAW" ;
  413.     
  414.             // open device context
  415.     if( lMode != 0L ) 
  416.         lType = lMode ;
  417.     else
  418.         lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
  419.  
  420.     return DevOpenDC( hab, //  WinQueryAnchorBlock( hwnd ),
  421.                       lType,
  422.                       "*",
  423.                       4L,
  424.                       (PDEVOPENDATA) &devop,
  425.                       NULL ) ;
  426.     }
  427.